<html>
    <head>
        <title>进入离开&列表过渡</title>
    </head>
    <body>
        <script>
            // 一、概述
                        /*
                            Vue 在插入、更新 或者移除DOM时，提供多种不同方式的应用过度效果。包括以下工具：

                                1. 在CSS过渡和动火中自动应用class
                                2. 可以配合使用第三方CSS动画库，如 Animate.css
                                3. 在过渡钩子函数中使用JavaScript 直接操作DOM
                                4. 可以配合使用第三方JavaScript动画库，如 Velocity.js

                                在这里，我们只会讲到 进入/离开 和 列表的过渡，你也可以看看下一节的"管理过渡状态"
                        */



            // 二、单个元素/组件的过渡
                        /*
                            Vue 提供了名为 transition 的封装组件，在下列情形中，可以给任何元素和组件添加 进入/离开 过渡：
                                1.条件渲染 (使用 v-if)
                                2.条件展示 (使用 v-show)
                                3.动态组件 
                                4.组件根节点

                            这里是一个典型的例子：

                                <div id="demo">
                                    <button v-on:click="show =!show">
                                        Toggle+
                                    </button>
                                    <transition name="fade">  
                                        <p v-if="show">hello</p>
                                    </transition>
                                </div>
                        */
                                new Vue({
                                    el:'#demo',
                                    data:{
                                        show:true
                                    }
                                });
                        
                        /*
                            当插入或删除包含咋 transition 组件中的元素时，Vue将会做以下处理：
                                
                                1.自动嗅探目标元素是否应用了css 过渡或动画，如果是，在恰当的时机 添加/删除 css 类型。
                                
                                2.如果过渡组件通过了 JavaScript钩子函数 ,这些钩子函数将在恰当的时机被调用。

                                3.如果没有找到JavaScript 钩子，且也没有检测到CSS过渡/动画， DOM操作(插入/删除)在下一帧中立即执行。
                                  （注意： 此指浏览器逐帧动画机制， 和 Vue的 nextTick概念不同）
                        */
                                

            // 三、过渡的类名

                        /*
                            在进入/离开的过渡中，会有6个class切换。

                                1、 v-enter: 定义进入过渡的开始状态。  
                                             在元素被插入之前生效，在元素被插入之后的下一帧移除。

                                2、 v-enter-active: 定义进入多度生效的状态。  
                                                在整个进入过渡的阶段中应用，在元素被插入之前生效,在过渡/动画完成之后移除。
                                                这个class可以被用来定义进入过渡的过程时间，延迟和曲线函数。

                                3、v-enter-to:   定义进入过渡的结束状态。 
                                                在元素被插入之后下一帧生效(与此同时 v-enter 被移除)

                                4、 v-leave:    定义离开过渡的开始状态。
                                                在元素被插入之后下一帧生效(于此同时 v-enter 被移除)，在过渡/动画完成之后移除。

                                5、 v-leave=active:  定义离开过渡生效的状态。
                                                在整个离开过渡的阶段中应用，在离开过渡被触发时立刻生效，在过渡/动画完成之后移除。
                                                这个类可以被用来定义离开多度的过程时间，延迟和曲线函数。
                                
                                6、 v-leave-to:  定义离开过渡的结束状态、
                                                在离开过渡被触发之后下一帧生效(于此同时 v-leave 被删除)，在过渡/动画完成之后移除.
                        */


            // 四、CSS过渡
                        /*
                            常用的过渡都是使用CSS过渡。

                            下面是一个简单的例子：

                                    <div id="example-1">
                                        <button v-on:click="show=!show">
                                                显示切换
                                        </button>
                                        <transition name="slide-fade">
                                            <p v-if="show">Hello</p>
                                        </transition>
                                    </div>
                        */
                                    new Vue({
                                        el:'#example-1',
                                        data:{
                                            show:true
                                        }
                                    })

                        /*
                            用于过渡的CSS类应该如下命名：  
                            --可以设置不同的进入和离开通动画---

                            --设置持续时间和动画函数---
                            .slide-fade-enter-active {
                                transition: all .3s ease;
                            }

                            .slide-fade-leave-active {
                                transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);  // CSS中使用过渡贝塞尔曲线
                            }

                            .slide-fade-enter, .slide-fade-leave-to{
                                transform: translateX(10px);
                                opacity: 0;
                            }
                        */


            // 五、CSS动画 
                        /*
                            CSS动画永华通CSS过渡，区别是在动画中 v-enter 类名在节点插入DOM后不会立即删除，而是在 animationend 事件触发时删除。

                            eg: (省略了兼容性前缀)
                                    <div id="example-2">
                                        <button v-on:click="show=!show"> Toggle Show </button>
                                        <transition name ="bounce">
                                            <p v-if="show"></p>
                                        </transition>
                                    </div>
                        */
                                    new Vue({
                                        el:'#example-2',
                                        data:{
                                            show:true
                                        }
                                    })

                        /*
                             .bounce-enter-active {
                                animation: bounce-in .5s;
                            }
                            .bounce-leave-active {
                                animation: bounce-in .5s reverse;
                            }
                            @keyframes bounce-in {
                                0% {
                                    transform: scale(0);
                                }
                                50% {
                                    transform: scale(1.5);
                                }
                                100% {
                                    transform: scale(1);
                                }
                            }       
                        */


            // 六、自定义过度的类名
                    /*
                        我们可以通过以下 attribute(标签属性) 来自定义过渡类型：
                            1、 enter-class
                            2、 enter-active-class
                            3、 enter-to-class
                            4、 leave-class
                            5、 leave-active-class
                            6、 leave-to-class

                        他们的优先级高于普通的类型，这对于Vue的过渡系统和其他第三方CSS动画库， 如 Animate.css 结合使用十分有用。
                    */
                    /*
                          eg:

                                    <link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">

                                    <div id="example-3">
                                        <button v-on:click="show=!show">
                                            Toggle show
                                        </button>
                                        <transition
                                            name="custom-classes-transition"
                                            enter-active-class="animated tada"
                                            leave-active-class="animated bounceOutRight"
                                        >
                                            <p v-if="show">hello</p>
                                        </transition>
                                    </div>
                    */  
                                    new Vue({
                                        el:'#example-3',
                                        data:{
                                            show:true
                                        }
                                    });

                
            // 七、同时使用过渡和动画
                    /*
                        Vue 为了知道过渡的完成，必须设置相应的事件监听器。
                        它可以使 transitioned 或  animationend，这取决于给元素应用的CSS规则。（在CSS使用animation 还是 transition ））
                        如果你使用其中任何一种，Vue能自动是被类型并设置监听器。

                        但是，在一些场景中，你需要给同一个元素同时设置两种过渡效果(animation 和 transition),
                        比如 animation 很快的被触发并完成了，而 transition效果还没结束。
                        在这种情况下，你就需要使用 type attribute(标签属性)并设置 animation 或 transition 来明确你需要Vue监听的类型。
                    */           


            // 八、显性的过渡持续时间
                    /*
                        在很多情况下，Vue 可以自动得出过渡效果的完成时机。默认情况下，Vue会等待其在过渡效果的"根元素"的第一个 transitioned 或 animationend 事件。
                        然而，也可以不这样设定---比如，我们可以拥有一个精心编排的一些列多度效果，其中一些嵌套的内部元素相比于过渡效果的根元素有延迟的或者更长的过渡效果。

                        在这种情况下，你可以用<transition>组件上的 duration attribute(标签属性) 来明确设置持续时间（以毫秒计）：

                            eg：  <transition :duration="{ enter: 5000, leave: 1000 }"> </transition>
                    */

            // 九、JavaScript钩子
                    /*
                        可以在 atrribute(标签属性)中声明JavaScript钩子：

                            <transition
                                v-on:before-enter="beforeEnter"
                                v-on:enter="enter"
                                v-on:after-enter="afterEnter"
                                v-on:enter-cancelled="enterCancelled"

                                v-on:before-leave="beforeLeave"
                                v-on:leave="leave"
                                v-on:after-leave="afterLeave"
                                v-on:leave-cancelled="leaveCancelled"
                            >

                            </transition>
                    */

                            new Vue({
                                el:'#example-5',
                                data:{

                                },
                                methods: {
                                    // 进入中
                                    beforeEnter: function (el) {
                                        // ...
                                    },

                                    // 当与CSS结合使用，回调函数 done 是可选的
                                    enter:function(del,done){
                                        // ...
                                        done();
                                    },
                                    afterEnter:function(el){
                                        // ...
                                    },
                                    enterCancelled:function(el){

                                    },

                                    // 离开时
                                    beforeLeave:function(el){
                                        // ...
                                    },
                                    // 当与CSS结合使用，回调函数 done 是可选的
                                    leave:function(el,done){
                                        // ...
                                        done();
                                    },
                                    afterLeave:function(el){
                                        // ...
                                    },
                                    leaveCancelled:function(el){

                                    }
                                },
                            })

                    /*
                        这些钩子函数可以结合CSS transition / animation 使用，也可以单独使用。


                        ★、注意：
                                 当只用JavaScript过渡的时候，在 enter 和 leave 中必须使用 done 进行回调。否则，它们将被同步调用，过渡会立即完成。


                                 推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false" ，这样Vue会跳过CSS的检测，这也可以避免过渡过程中 CSS的影响。
                    */

                    // 一个实用Velocity.js(js动画库) 的简单例子
                                /*
                                    --Velocity 和 jQuery.animate 的工作方式类似，也是用来实现 JavaScript 动画的一个很棒的选择--

                                    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"><-/script>
                                    <div id="example-4">
                                        <button @click="show = !show">
                                            Toggle
                                        </button>
                                        <transition
                                            v-on:before-enter="beforeEnter"
                                            v-on:enter="enter"
                                            v-on:leave="leave"
                                            v-bind:css="false"
                                        >
                                            <p v-if="show">
                                                Demo
                                            </p>
                                        </transition>
                                    </div>
                                */
                               new Vue({
                                   el:'#example-6',
                                   data:{
                                     show:false
                                   },
                                   methods:{
                                       beforeEnter:function(el){
                                            el.style.opacity = 0
                                            el.style.transformOrigin = 'left'
                                       },
                                       enter:function(el,done){
                                            Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
                                            Velocity(el, { fontSize: '1em' }, { complete: done })
                                       },
                                       leave:function(el,done){
                                            Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
                                            Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
                                            Velocity(el, {
                                                rotateZ: '45deg',
                                                translateY: '30px',
                                                translateX: '30px',
                                                opacity: 0
                                            }, { complete: done })
                                            }
                                       }
                               });
        </script>
    </body>
</html>